﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.DataModel;
using YArchitech.Revit;

namespace YArchitech.Plumbing
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class LayWares : IExternalCommand
	{
		public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			Transaction transaction = null;
			Result result;
			try
			{
				if (commandData == null)
				{
					throw new System.ArgumentNullException();
				}
				this.m_Revit = commandData;
				UIApplication application = commandData.Application;
				this.uiDoc = application.ActiveUIDocument;
				this.doc = this.uiDoc.Document;
				this.sel = this.uiDoc.Selection;
				List<ViewType> list = new List<ViewType>();
                list.Add((ViewType)1);
                list.Add((ViewType)2);
                list.Add((ViewType)4);
                list.Add((ViewType)3);
                list.Add((ViewType)116);
				if (!YJKRevitTools.ViewCheck(application.ActiveUIDocument, list))
				{
					result = Autodesk.Revit.UI.Result.Succeeded;
				}
				else
				{
					transaction = new Transaction(this.doc, "layware");
					this.formWares = new FormWares(this.doc, this.uiDoc, application);
					this.formWares.ShowDialog();
					transaction.Start();
					if (this.formWares.DialogResult == DialogResult.OK)
					{
						try
						{
							FamilySymbol fs = this.formWares.fs;
							fs.Activate();
							if (fs == null)
							{
								YJKMessageBox.Show("未选择有效的族");
								return Autodesk.Revit.UI.Result.Cancelled;
							}
							if (this.formWares.layType == 0)
							{
								transaction.Commit();
								List<ElementId> familyList = this.GetFamilyList(fs);
								try
								{
									this.uiDoc.PromptForFamilyInstancePlacement(fs);
								}
								catch (Exception)
								{
								}
								transaction.Start();
								FamilyInstance familyInstance = this.doc.Create.NewFamilyInstance(new XYZ(0.0, 0.0, 0.0), fs, (Autodesk.Revit.DB.Structure.StructuralType)0);
								new SetSanitaryHelper(this.uiDoc);
								this.doc.Regenerate();
								this.WriteExtensionData(familyInstance);
								this.doc.DeleteElement(familyInstance);
								foreach (ElementId elementId in this.GetFamilyList(fs))
								{
									bool flag = false;
									using (List<ElementId>.Enumerator enumerator2 = familyList.GetEnumerator())
									{
										while (enumerator2.MoveNext())
										{
											if (enumerator2.Current.IntegerValue == elementId.IntegerValue)
											{
												flag = true;
											}
										}
									}
									if (!flag)
									{
										SetParaForInstance.SetOffsetForInstance(this.doc.GetElement(elementId), this.formWares.elevation / 1000.0, this.doc);
									}
								}
								transaction.Commit();
								return Autodesk.Revit.UI.Result.Succeeded;
							}
							if (this.formWares.layType == 1)
							{
								XYZ xyz = new XYZ();
								XYZ xyz2 = new XYZ();
								double num = 0.0;
								bool flag2 = true;
								bool flag3 = false;
								Line line = null;
								List<XYZ> list2 = new List<XYZ>();
								Transform transform = null;
								Curve curve = this.SelectWall(ref xyz, ref xyz2, ref num, ref flag2, ref flag3, ref transform);
								if (!flag3)
								{
									line = (curve as Line);
								}
								if (line == null)
								{
									YJKMessageBox.Show("没有选到墙边线，请将鼠标放到墙边线上，亮显后再确定！");
								}
								if (!(line != null))
								{
									goto IL_C39;
								}
								YJKLine hyline = new YJKLine(line);
								double num2 = 100000.0;
								if (hyline.StartPoint.X != hyline.EndPoint.X)
								{
									num2 = hyline.lookForK(hyline.StartPoint, hyline.EndPoint);
								}
								XYZ calPoint;
								if (flag2)
								{
									calPoint = new XYZ(xyz2.X, xyz2.Y + 0.1, xyz2.Z);
									if (num2 == 0.0)
									{
										num2 = -1E-06;
									}
								}
								else
								{
									calPoint = new XYZ(xyz2.X, xyz2.Y - 0.1, xyz2.Z);
									if (num2 == 0.0)
									{
										num2 = 1E-06;
									}
								}
								if (num2 > 1000.0 || num2 < -1000.0)
								{
									if (flag2)
									{
										calPoint = new XYZ(xyz2.X - 1.0, xyz2.Y, xyz2.Z);
									}
									else
									{
										calPoint = new XYZ(xyz2.X + 1.0, xyz2.Y, xyz2.Z);
									}
								}
								int num3 = this.GetPointPosition(xyz, xyz2, calPoint);
								int num6;
								if (num2 != 0.0)
								{
									double num4 = xyz.Y + 1.0 / num2 * xyz.X;
									double num5 = -1.0 / num2 * (xyz.X + 1.0) + num4;
									num6 = this.GetPointPosition(xyz, new XYZ(xyz.X + 1.0, num5, xyz.Z), calPoint);
								}
								else
								{
									num6 = this.GetPointPosition(xyz, new XYZ(xyz.X + 1.0, xyz.Y, xyz.Z), calPoint);
								}
								if (num2 > 0.0)
								{
									num3 = -num3;
									num6 = -num6;
								}
								XYZ xyz3;
								if (num2 != 0.0)
								{
									xyz3 = this.GetPos(this.GetPos(xyz, num2, (double)this.formWares.wallPointDistance / 304.8, -num6), -1.0 / num2, (double)this.formWares.wallFaceDistance / 304.8, num3);
									list2.Add(xyz3);
								}
								else
								{
									xyz3 = new XYZ(xyz.X + (double)(-(double)num6 * this.formWares.wallFaceDistance) / 304.8, xyz.Y + (double)(-(double)num3 * this.formWares.wallPointDistance) / 304.8, xyz.Z);
									list2.Add(xyz3);
								}
								for (int i = 1; i < this.formWares.equipCount; i++)
								{
									if (num2 != 0.0)
									{
										XYZ pos = this.GetPos(xyz3, num2, (double)(this.formWares.equipDistance * i) / 304.8, -num6);
										list2.Add(pos);
									}
									else
									{
										XYZ item = new XYZ(xyz.X + (double)(-(double)num6 * this.formWares.wallFaceDistance) / 304.8, xyz.Y + (double)this.formWares.wallPointDistance / 304.8 + (double)(-(double)num3 * i * this.formWares.equipDistance) / 304.8, xyz.Z);
										list2.Add(item);
									}
								}
								using (List<XYZ>.Enumerator enumerator3 = list2.GetEnumerator())
								{
									while (enumerator3.MoveNext())
									{
										XYZ xyz4 = enumerator3.Current;
										XYZ xyz5 = xyz4;
										if (transform != null)
										{
											xyz5 = xyz4 + transform.Origin;
										}
										UnifiedModified.ActivateFamilySymbol(fs);
										FamilyInstance familyInstance2 = this.doc.Create.NewFamilyInstance(new XYZ(xyz5.X, xyz5.Y, this.formWares.elevation / 304.8), fs, this.uiDoc.ActiveView.GenLevel, (Autodesk.Revit.DB.Structure.StructuralType)0);
										this.doc.Regenerate();
										double num7 = Math.Atan(num2);
										if (num3 == 1)
										{
											if (num2 > 0.0)
											{
												num7 = Math.PI - num7;
											}
											else
											{
												num7 = -num7;
											}
										}
										else if (num2 > 0.0)
										{
											num7 = -num7;
										}
										else
										{
											num7 = Math.PI - num7;
										}
										ElementTransformUtils.RotateElement(this.doc, familyInstance2.Id, Line.CreateBound(xyz5, new XYZ(xyz5.X, xyz5.Y, xyz5.Z + 1.0)), Math.PI - num7);
										try
										{
											this.WriteExtensionData(familyInstance2);
										}
										catch
										{
										}
									}
									goto IL_C39;
								}
							}
							if (this.formWares.layType == 2)
							{
								Element elementByRef;
								for (;;)
								{
									Reference reference = this.uiDoc.Selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, "请选择一个卫浴：");
									elementByRef = this.uiDoc.Document.GetElementByRef(reference);
									if (!(elementByRef.Category.Name != "卫浴装置") || !(elementByRef.Category.Name != "管道附件"))
									{
										break;
									}
									YJKMessageBox.Show("请选择一个卫浴装置或地漏！");
								}
								if (elementByRef == null)
								{
									goto IL_C39;
								}
								FamilyInstance familyInstance3 = elementByRef as FamilyInstance;
								XYZ point = (familyInstance3.Location as LocationPoint).Point;
								double twoXYVectorAngle = YJKRevitTools.GetTwoXYVectorAngle(new XYZ(0.0, 1.0, 0.0), familyInstance3.FacingOrientation);
								double num8 = Math.Tan(twoXYVectorAngle);
								string text;
								if (this.formWares.isByNumber)
								{
									text = "请选择卫浴一侧的点做为布置方向：";
								}
								else
								{
									text = "请选择卫浴一侧的点做为布置方向和到点位置：";
								}
								new List<XYZ>();
								XYZ xyz6 = this.uiDoc.Selection.PickPoint(text);
								double elevation = this.uiDoc.ActiveView.GenLevel.Elevation;
								double num9 = 0.0;
								double num11;
								if (num8 != 0.0)
								{
									num8 = -1.0 / num8;
									double num10 = point.Y - num8 * point.X;
									num11 = (double)(-(double)this.GetPointPosition(point, new XYZ(point.X + 1.0, num8 * (point.X + 1.0) + num10, point.Z), xyz6));
									num9 = Math.Abs(num8 * xyz6.X - xyz6.Y + num10) / Math.Sqrt(num8 * num8 + 1.0);
								}
								else
								{
									num11 = (double)(-(double)this.GetPointPosition(point, new XYZ(point.X, point.Y + 1.0, point.Z), xyz6));
								}
								if (this.formWares.isByNumber)
								{
									num9 = (double)(this.formWares.wareCount * this.formWares.distance) / 304.8;
								}
								double num12 = twoXYVectorAngle;
								if (num12 > Math.PI)
								{
									num12 -= Math.PI;
								}
								double num13 = point.X - num11 * Math.Sin(Math.PI*.5 - num12) * (num9 + 0.1);
								double num14 = point.Y - num11 * Math.Cos(Math.PI*.5 - num12) * (num9 + 0.1);
								XYZ xyz7 = new XYZ(num13, num14, point.Z);
								List<XYZ> layLineXYZList = new YJKLine(Line.CreateBound(point, xyz7)).GetLayLineXYZList(point, (double)this.formWares.distance / 304.8, 0.0, point.Z);
								double num15 = (double)this.formWares.offset / 304.8 * Math.Sin(twoXYVectorAngle);
								double num16 = (double)this.formWares.offset / 304.8 * Math.Cos(twoXYVectorAngle);
								if (layLineXYZList.Count < 2)
								{
									YJKMessageBox.Show("布置的实例个数为0！请调整方向后再布置！");
								}
								using (List<XYZ>.Enumerator enumerator3 = layLineXYZList.GetEnumerator())
								{
									while (enumerator3.MoveNext())
									{
										XYZ xyz8 = enumerator3.Current;
										if (xyz8.DistanceTo(point) > 0.1)
										{
											UnifiedModified.ActivateFamilySymbol(fs);
											FamilyInstance familyInstance4 = this.doc.Create.NewFamilyInstance(new XYZ(xyz8.X + num15, xyz8.Y + num16, this.formWares.elevation / 304.8), fs, this.uiDoc.ActiveView.GenLevel, (Autodesk.Revit.DB.Structure.StructuralType)0);
											this.doc.Regenerate();
											XYZ point2 = (familyInstance4.Location as LocationPoint).Point;
											ElementTransformUtils.RotateElement(this.doc, familyInstance4.Id, Line.CreateBound(point2, new XYZ(point2.X, point2.Y, point2.Z + 1.0)), twoXYVectorAngle);
											try
											{
												this.WriteExtensionData(familyInstance4);
											}
											catch
											{
											}
										}
									}
									goto IL_C39;
								}
							}
							YJKMessageBox.Show("请选择于XY面垂直的墙！");
							this.formWares.CloseDocuments();
							return Autodesk.Revit.UI.Result.Failed;
							IL_C39:;
						}
						catch (Autodesk.Revit.Exceptions.OperationCanceledException)
						{
						}
					}
					result = Autodesk.Revit.UI.Result.Succeeded;
				}
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
				if (transaction != null && (int)transaction.GetStatus() != 3)
				{
					transaction.Commit();
				}
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception ex)
			{
				message = ex.Message;
				result = Autodesk.Revit.UI.Result.Failed;
			}
			finally
			{
				if (this.formWares != null)
				{
					this.formWares.Dispose();
				}
				if (transaction != null)
				{
					if ((int)transaction.GetStatus() == 1)
					{
						transaction.Commit();
					}
					if ((int)transaction.GetStatus() != 3 && (int)transaction.GetStatus() != 2)
					{
						transaction.RollBack();
					}
				}
			}
			return result;
		}

		private void WriteExtensionData(Element ele)
		{
			List<Element> list = new List<Element>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.doc);
			filteredElementCollector.OfCategory(BuiltInCategory.OST_PlumbingFixtures);
			filteredElementCollector.OfClass(typeof(FamilyInstance));
			foreach (Element element in filteredElementCollector)
			{
				FamilyInstance familyInstance = ele as FamilyInstance;
				if (familyInstance != null && (element as FamilyInstance).Symbol.Family.Name.Equals(familyInstance.Symbol.Family.Name))
				{
					list.Add(element);
				}
			}
			foreach (Element elem in list)
			{
				try
				{
					SetSanitaryData setSanitaryData = YJKRevitTools.GetSetSanitaryData(this.doc, elem);
					if (setSanitaryData != null)
					{
						new SetSanitaryHelper(this.uiDoc).WriteExtendData(setSanitaryData, elem);
						break;
					}
				}
				catch
				{
				}
			}
		}

		private int GetPointPosition(XYZ originPoint, XYZ linePoint, XYZ calPoint)
		{
			if (Math.Abs(linePoint.X - originPoint.X) < 0.001)
			{
				if (linePoint.X < calPoint.X)
				{
					return 1;
				}
				return -1;
			}
			else
			{
				double num = (linePoint.Y - originPoint.Y) / (linePoint.X - originPoint.X);
				double num2 = linePoint.Y - num * linePoint.X;
				if (num * calPoint.X + num2 < calPoint.Y)
				{
					return 1;
				}
				return -1;
			}
		}

		private XYZ GetPos(XYZ oriPos, double k, double fLen, int d1)
		{
			if (k < 10000.0)
			{
				double num = (double)d1 * Math.Sqrt(fLen * fLen / (k * k + 1.0)) + oriPos.X;
				double num2 = k * (num - oriPos.X) + oriPos.Y;
				return new XYZ(num, num2, oriPos.Z);
			}
			return new XYZ(oriPos.X, oriPos.Y + (double)d1 * fLen, oriPos.Z);
		}

		private List<ElementId> GetFamilyList(FamilySymbol fs)
		{
			List<ElementId> list = new List<ElementId>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.doc);
			filteredElementCollector.OfCategory((Autodesk.Revit.DB.BuiltInCategory)(fs.Category.Id.IntegerValue));
			filteredElementCollector.OfClass(typeof(FamilyInstance));
			foreach (Element element in filteredElementCollector)
			{
				list.Add(element.Id);
			}
			return list;
		}

		private double GetB(XYZ point1, XYZ point2)
		{
			if (point1.X - point2.X == 0.0)
			{
				return double.MaxValue;
			}
			double num = (point1.Y - point2.Y) / (point1.X - point2.X);
			return point1.Y - num * point1.X;
		}

		private Curve SelectWall(ref XYZ startPoint, ref XYZ endPoint, ref double z, ref bool isUpLine, ref bool isArcWall, ref Transform trans)
		{
			Reference reference = null;
			Line line = null;
			try
			{
                SelectedElement selectedElement = this.uiDoc.PickElementsByFace<Element>("请选择要布置的参考墙面", ref reference, ref trans, 0.05);
				if (selectedElement == null)
				{
					return line;
				}
				Element element = selectedElement.Element;
				Wall wall = element as Wall;
				z = this.uiDoc.ActiveView.GenLevel.Elevation;
				Options options = new Options();
				options.ComputeReferences = true;
				PlanarFace planarFace = null;
				try
				{
                    IList<Reference> references = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Exterior);
                    if (references.Count > 0)
                    {
                        var reference2 = references[0];
                        GeometryObject sideFaceGeo = wall.GetGeometryObjectFromReference(reference2);

                        // 转型成我们想要的对象 
                        planarFace = sideFaceGeo as PlanarFace;
                    }

                    //planarFace = ((element.GetGeometryObjectFromReference(reference) as Face) as PlanarFace);
                    if (planarFace == null)
                    {
                        planarFace = this.GetNearestFaceFromElement(element, reference.GlobalPoint, trans);
                    }
				}
				catch (Exception)
				{
					planarFace = this.GetNearestFaceFromElement(element, reference.GlobalPoint, trans);
				}
				Line line2 = null;
				double num = double.MaxValue;
				double num2 = double.MinValue;
				double num3 = 0.0;

                int nEdge = planarFace.EdgeLoops.get_Item(0).Size;

				bool flag = false;
				foreach (object obj in planarFace.EdgeLoops.get_Item(0))
				{
					Edge edge = (Edge)obj;
					if (edge.Tessellate().Count == 2)
					{
						if (Math.Abs(edge.Tessellate()[0].Z - edge.Tessellate()[1].Z) < 0.01)
						{
							flag = true;
							Line line3 = Line.CreateBound(edge.Tessellate()[0], edge.Tessellate()[1]);
							double num4 = line3.Distance(reference.GlobalPoint);
							if (trans != null)
							{
								num4 = line3.Distance(reference.GlobalPoint - trans.Origin);
							}
							if (num4 < num)
							{
								num = num4;
								num3 = this.GetB(edge.Tessellate()[0], edge.Tessellate()[1]);
								line2 = line3;
							}
						}
					}
					else
					{
						isArcWall = true;
					}
				}
				if (!flag)
				{
					return null;
				}
				line = line2;
				foreach (GeometryObject geometryObject in wall.get_Geometry(options))
				{
					if (geometryObject is Solid)
					{
						Solid solid = geometryObject as Solid;
						if (solid != null && solid.Edges.Size > 0)
						{
							foreach (object obj2 in solid.Edges)
							{
								Edge edge2 = (Edge)obj2;
								if (Math.Abs(edge2.Tessellate()[0].Z - edge2.Tessellate()[1].Z) < 0.01)
								{
									YJKLine hyline = new YJKLine(edge2.Tessellate()[0], edge2.Tessellate()[1]);
									if (Math.Abs(line.Tessellate()[0].Y - line.Tessellate()[1].Y) < 0.01)
									{
										if (Math.Abs(edge2.Tessellate()[0].Y - edge2.Tessellate()[1].Y) < 0.01)
										{
											num3 = line.Tessellate()[0].Y;
											if (edge2.Tessellate()[0].Y > num2)
											{
												num2 = edge2.Tessellate()[0].Y;
											}
										}
									}
									else if (Math.Abs(line.Tessellate()[0].X - line.Tessellate()[1].X) < 0.01)
									{
										if (Math.Abs(edge2.Tessellate()[0].X - edge2.Tessellate()[1].X) < 0.01)
										{
											num3 = line.Tessellate()[0].X;
											if (edge2.Tessellate()[0].X > num2)
											{
												num2 = edge2.Tessellate()[0].X;
											}
										}
									}
									else if (Math.Abs(1.0 - hyline.lookForK(edge2.Tessellate()[0], edge2.Tessellate()[1]) / hyline.lookForK(line.Tessellate()[0], line.Tessellate()[1])) < 0.01 && this.GetB(edge2.Tessellate()[0], edge2.Tessellate()[1]) > num2)
									{
										num2 = this.GetB(edge2.Tessellate()[0], edge2.Tessellate()[1]);
									}
								}
							}
						}
					}
				}
				if (num3 - num2 < -0.01)
				{
					isUpLine = false;
				}
				else
				{
					isUpLine = true;
				}
				if (line != null)
				{
					YJKLine hyline2 = new YJKLine(line);
					startPoint = hyline2.GetNearlyPoint(reference.GlobalPoint);
					if (trans != null)
					{
						startPoint = hyline2.GetNearlyPoint(reference.GlobalPoint - trans.Origin);
					}
					if (startPoint.DistanceTo(line.Tessellate()[0]) > startPoint.DistanceTo(line.Tessellate()[1]))
					{
						endPoint = line.Tessellate()[0];
					}
					else
					{
						endPoint = line.Tessellate()[1];
					}
				}
			}
			catch (Exception ex)
			{
                string sss = ex.Message;
				return line;
			}
			return line;
		}

		private bool isVerticalFace(Face f)
		{
			foreach (object obj in f.EdgeLoops.get_Item(0))
			{
				Edge edge = (Edge)obj;
				if (Math.Abs(edge.Tessellate()[0].Z - edge.Tessellate()[1].Z) > 0.1)
				{
					return true;
				}
			}
			return false;
		}

		private PlanarFace GetNearestFaceFromElement(Element e, XYZ globalPoint, Transform trans)
		{
			PlanarFace result = null;
			try
			{
				foreach (GeometryObject geometryObject in (e as Wall).get_Geometry(new Options
				{
					ComputeReferences = true
				}))
				{
					if (geometryObject is Solid)
					{
						Solid solid = geometryObject as Solid;
						if (solid != null && solid.Edges.Size > 0)
						{
							double num = double.MaxValue;
							foreach (object obj in solid.Faces)
							{
								Face face = (Face)obj;
								if (this.isVerticalFace(face))
								{
									int num2 = 0;
									double num3 = double.MaxValue;
									foreach (object obj2 in face.EdgeLoops.get_Item(0))
									{
										Edge edge = (Edge)obj2;
										num2++;
										if (Math.Abs(edge.Tessellate()[0].Z - edge.Tessellate()[1].Z) < 0.1)
										{
                                            Line line3 = Line.CreateBound(edge.Tessellate()[0], edge.Tessellate()[1]);
                                            double num4 = line3.Distance(globalPoint);
                                            if (trans != null)
                                            {
                                                num4 = line3.Distance(globalPoint - trans.Origin);
                                            }
                                            
											if (num4 < num3)
											{
												num3 = num4;
											}
										}
									}
									if (num3 < num)
									{
										num = num3;
										result = (face as PlanarFace);
									}
								}
							}
						}
					}
				}
			}
			catch (Exception ex)
			{
                string sss = ex.Message;
                int kkk = 0;
			}
			return result;
		}

		private Autodesk.Revit.DB.View GetElementView(Element e, int type)
		{
			Autodesk.Revit.DB.View result = null;
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(e.Document);
			filteredElementCollector.OfClass(typeof(ViewPlan));
			foreach (Element element in filteredElementCollector)
			{
				Autodesk.Revit.DB.View view = element as Autodesk.Revit.DB.View;
				try
				{
					FilteredElementCollector filteredElementCollector2 = new FilteredElementCollector(e.Document, view.Id);
					if (type == 1)
					{
						filteredElementCollector2.OfClass(typeof(Wall));
					}
					else
					{
						filteredElementCollector2.OfClass(typeof(FamilyInstance));
					}
					IEnumerator<Element> enumerator2 = filteredElementCollector2.ToElements().GetEnumerator();
					{
						while (enumerator2.MoveNext())
						{
							if (enumerator2.Current.Id.IntegerValue.Equals(e.Id.IntegerValue))
							{
								result = view;
								return result;
							}
						}
					}
				}
				catch
				{
				}
			}
			return result;
		}

		private Document doc;

		private Selection sel;

		private UIDocument uiDoc;

		private FormWares formWares;

		private ExternalCommandData m_Revit;

		private struct threadData
		{
			public threadData(UIDocument _uidoc, FormWares _formWares)
			{
				this.uiDoc = _uidoc;
				this.formWares = _formWares;
			}

			public UIDocument uiDoc;

			public FormWares formWares;
		}
	}
}
